/**
 * @file test_optimizer.cpp
 * @brief 优化器测试用例
 * @author VimLVM Team
 * @date 2025
 */

#include <gtest/gtest.h>
#include "viml/optimizer.h"
#include "viml/instruction.h"
#include <memory>

using namespace viml;

/**
 * @brief 测试优化器基本创建
 */
TEST(OptimizerTest, BasicCreation) {
    auto optimizer = OptimizerFactory::create(OptimizationLevel::BASIC);
    EXPECT_NE(optimizer, nullptr);
    
    EXPECT_EQ(optimizer->get_stats().instructions_removed, 0);
    EXPECT_EQ(optimizer->get_stats().instructions_replaced, 0);
    EXPECT_EQ(optimizer->get_stats().constants_folded, 0);
}

/**
 * @brief 测试优化级别转换
 */
TEST(OptimizerTest, OptimizationLevelConversion) {
    EXPECT_EQ(OptimizerFactory::from_string("none"), OptimizationLevel::NONE);
    EXPECT_EQ(OptimizerFactory::from_string("basic"), OptimizationLevel::BASIC);
    EXPECT_EQ(OptimizerFactory::from_string("advanced"), OptimizationLevel::ADVANCED);
    EXPECT_EQ(OptimizerFactory::from_string("invalid"), OptimizationLevel::BASIC);
    
    EXPECT_EQ(OptimizerFactory::to_string(OptimizationLevel::NONE), "none");
    EXPECT_EQ(OptimizerFactory::to_string(OptimizationLevel::BASIC), "basic");
    EXPECT_EQ(OptimizerFactory::to_string(OptimizationLevel::ADVANCED), "advanced");
}

/**
 * @brief 测试常量折叠优化
 */
TEST(OptimizerTest, ConstantFolding) {
    // 创建测试函数
    std::vector<Instruction> bytecode;
    bytecode.push_back(Instruction::load_const(0, 0));  // 加载常量42
    bytecode.push_back(Instruction::load_const(1, 1));  // 加载常量100
    bytecode.push_back(Instruction::binary_op(OpCode::ADD, 2, 0, 1));  // 42 + 100
    bytecode.push_back(Instruction(OpCode::RETURN_OP, 2));
    
    std::vector<Value> constants;
    constants.push_back(Value(42.0));
    constants.push_back(Value(100.0));
    
    auto function = std::make_shared<Function>("test", std::vector<std::string>(), bytecode, 3);
    function->constants = constants;
    
    auto optimizer = OptimizerFactory::create(OptimizationLevel::BASIC);
    auto optimized = optimizer->optimize(function);
    
    EXPECT_NE(optimized, nullptr);
    EXPECT_GT(optimized->constants.size(), 0);
    
    const auto& stats = optimizer->get_stats();
    EXPECT_GE(stats.optimization_time_ms, 0.0);
}

/**
 * @brief 测试死代码消除
 */
TEST(OptimizerTest, DeadCodeElimination) {
    // 创建包含死代码的测试函数
    std::vector<Instruction> bytecode;
    bytecode.push_back(Instruction::load_const(0, 0));  // 加载常量10
    bytecode.push_back(Instruction::load_const(1, 1));  // 加载常量20
    bytecode.push_back(Instruction::binary_op(OpCode::ADD, 2, 0, 1));  // 10 + 20
    bytecode.push_back(Instruction(OpCode::RETURN_OP, 2));  // 返回结果
    bytecode.push_back(Instruction::load_const(3, 2));  // 死代码：未使用的常量
    
    std::vector<Value> constants;
    constants.push_back(Value(10.0));
    constants.push_back(Value(20.0));
    constants.push_back(Value(100.0));
    
    auto function = std::make_shared<Function>("test", std::vector<std::string>(), bytecode, 4);
    function->constants = constants;
    
    size_t original_size = function->bytecode.size();
    
    auto optimizer = OptimizerFactory::create(OptimizationLevel::BASIC);
    auto optimized = optimizer->optimize(function);
    
    EXPECT_LE(optimized->bytecode.size(), original_size);
    
    const auto& stats = optimizer->get_stats();
    EXPECT_GE(stats.dead_code_removed, 0);
}

/**
 * @brief 测试窥孔优化
 */
TEST(OptimizerTest, PeepholeOptimization) {
    // 创建测试字节码：LOAD_CONST 0, 0; LOAD_CONST 1, 1; ADD 2, 0, 1; RETURN 2
    std::vector<Instruction> bytecode;
    bytecode.push_back(Instruction::load_const(0, 0));
    bytecode.push_back(Instruction::load_const(1, 1));
    bytecode.push_back(Instruction::binary_op(OpCode::ADD, 2, 0, 1));
    bytecode.push_back(Instruction(OpCode::RETURN_OP, 2));
    
    std::vector<Value> constants;
    constants.push_back(Value(42.0));
    constants.push_back(Value(100.0));
    
    auto function = std::make_shared<Function>("test", std::vector<std::string>(), bytecode, 3);
    function->constants = constants;
    
    size_t original_size = function->bytecode.size();
    
    auto optimizer = OptimizerFactory::create(OptimizationLevel::BASIC);
    auto optimized = optimizer->optimize(function);
    
    EXPECT_LE(optimized->bytecode.size(), original_size);
    
    const auto& stats = optimizer->get_stats();
    EXPECT_GE(stats.instructions_removed, 0);
}

/**
 * @brief 测试内联缓存
 */
TEST(OptimizerTest, InlineCache) {
    InlineCache cache;
    
    EXPECT_EQ(cache.get_stats().total_lookups, 0);
    EXPECT_EQ(cache.get_stats().cache_hits, 0);
    EXPECT_EQ(cache.get_stats().cache_misses, 0);
    
    InlineCacheEntry entry;
    entry.type = ValueType::NUMBER;
    entry.cached_value = nullptr;
    entry.hit_count = 10;
    entry.miss_count = 2;
    
    EXPECT_TRUE(cache.add_entry(entry));
    
    auto* retrieved = cache.get_entry(0);
    EXPECT_NE(retrieved, nullptr);
    EXPECT_EQ(retrieved->type, ValueType::NUMBER);
    EXPECT_EQ(retrieved->hit_count, 10);
    EXPECT_EQ(retrieved->miss_count, 2);
    EXPECT_NEAR(retrieved->hit_rate(), 10.0/12.0, 0.001);
}

/**
 * @brief 测试无优化模式
 */
TEST(OptimizerTest, NoOptimization) {
    // 创建测试函数
    std::vector<Instruction> bytecode;
    bytecode.push_back(Instruction::load_const(0, 0));
    bytecode.push_back(Instruction(OpCode::RETURN_OP, 0));
    
    std::vector<Value> constants;
    constants.push_back(Value(10.0));
    
    auto function = std::make_shared<Function>("test", std::vector<std::string>(), bytecode, 1);
    function->constants = constants;
    
    auto optimizer = OptimizerFactory::create(OptimizationLevel::NONE);
    auto optimized = optimizer->optimize(function);
    
    // 无优化时应该返回原函数
    EXPECT_EQ(optimized, function);
    
    const auto& stats = optimizer->get_stats();
    EXPECT_EQ(stats.instructions_removed, 0);
    EXPECT_EQ(stats.instructions_replaced, 0);
    EXPECT_EQ(stats.constants_folded, 0);
    EXPECT_EQ(stats.dead_code_removed, 0);
    EXPECT_EQ(stats.common_subexpressions, 0);
    EXPECT_EQ(stats.optimization_time_ms, 0.0);
}

/**
 * @brief 测试高级优化
 */
TEST(OptimizerTest, AdvancedOptimization) {
    // 创建包含公共子表达式的测试函数
    std::vector<Instruction> bytecode;
    bytecode.push_back(Instruction::load_const(0, 0));  // x = 10
    bytecode.push_back(Instruction::load_const(1, 1));  // y = 20
    bytecode.push_back(Instruction::binary_op(OpCode::ADD, 2, 0, 1));  // z = x + y
    bytecode.push_back(Instruction::binary_op(OpCode::ADD, 3, 0, 1));  // w = x + y (公共子表达式)
    bytecode.push_back(Instruction::binary_op(OpCode::ADD, 4, 2, 3));  // return z + w
    bytecode.push_back(Instruction(OpCode::RETURN_OP, 4));
    
    std::vector<Value> constants;
    constants.push_back(Value(10.0));
    constants.push_back(Value(20.0));
    
    auto function = std::make_shared<Function>("test", std::vector<std::string>(), bytecode, 5);
    function->constants = constants;
    
    auto optimizer = OptimizerFactory::create(OptimizationLevel::ADVANCED);
    auto optimized = optimizer->optimize(function);
    
    EXPECT_NE(optimized, nullptr);
    
    const auto& stats = optimizer->get_stats();
    EXPECT_GE(stats.common_subexpressions, 0);
}

/**
 * @brief 测试优化统计重置
 */
TEST(OptimizerTest, ResetStats) {
    auto optimizer = OptimizerFactory::create(OptimizationLevel::BASIC);
    
    // 创建测试函数
    std::vector<Instruction> bytecode;
    bytecode.push_back(Instruction::load_const(0, 0));
    bytecode.push_back(Instruction::binary_op(OpCode::ADD, 1, 0, 0));
    bytecode.push_back(Instruction(OpCode::RETURN_OP, 1));
    
    std::vector<Value> constants;
    constants.push_back(Value(1.0));
    
    auto function = std::make_shared<Function>("test", std::vector<std::string>(), bytecode, 2);
    function->constants = constants;
    
    // 执行优化
    optimizer->optimize(function);
    
    // 重置统计信息
    optimizer->reset_stats();
    
    const auto& stats = optimizer->get_stats();
    EXPECT_EQ(stats.instructions_removed, 0);
    EXPECT_EQ(stats.instructions_replaced, 0);
    EXPECT_EQ(stats.constants_folded, 0);
    EXPECT_EQ(stats.dead_code_removed, 0);
    EXPECT_EQ(stats.common_subexpressions, 0);
    EXPECT_EQ(stats.optimization_time_ms, 0.0);
}